<script setup lang="ts">
import {reactive, computed, ref, onMounted, onUnmounted, getCurrentInstance, defineEmits} from "vue";
import { resetSize } from '@/util/util'
import { getBlockPuzzleCaptchaInfo, verifyBlockPuzzleCaptchaInfo } from '@/api/captcha/index.ts'
// defineProps(["vSpace", "explain", "imgSize", "blockSize", "barSize"])

const emit = defineEmits(['myclick'])

export interface Props {
  vSpace: number,
  explain: string,
  imgSize: Object,
  blockSize: Object,
  barSize: Object,
}

const props = withDefaults(defineProps<Props>(), {
  vSpace: 5,
  explain: "",
  imgSize: () => {
    return {
      width: '310px',
      height: '155px',
    }
  },
  blockSize: () => {
    return {
      width: '50px',
      height: '50px',
    }
  },
  barSize: () => {
    return {
      width: '310px',
      height: '34px',
    }
  },
})

const { proxy } = getCurrentInstance()

const data = reactive({
  passFlag: '', // 是否通过的标识
  backImgBase: '' +
      '', // 验证码背景图片
  blockBackImgBase: '', // 验证滑块的背景图片
  backToken: '', // 后端返回的唯一token值
  startMoveTime: '', // 移动开始的时间
  endMovetime: '', // 移动结束的时间
  tipsBackColor: '', // 提示词的背景颜色
  tipWords: '',
  text: '',
  finishText: '',
  setSize: {
    imgHeight: 0,
    imgWidth: 0,
    barHeight: 0,
    barWidth: 0,
  },
  top: 0,
  left: 0,
  moveBlockLeft: undefined,
  leftBarWidth: undefined,
  // 移动中样式
  moveBlockBackgroundColor: undefined,
  moveLeftBarBackgroundColor: '#fff',
  iconColor: undefined,
  iconClass: 'icon-right',
  status: false, // 鼠标状态
  isEnd: false, // 是够验证完成
  showRefresh: true,
  transitionLeft: '',
  transitionWidth: '',
  defaultImg: "",
  startLeft: undefined,
  backToken: "",
  showRefresh: true,
})
const inner_base = ref()

onMounted(() => {
  data.text = props.explain
  proxy.$nextTick(() => {
    const setSize = resetSize(proxy); // 重新设置宽度高度
    for (const key in setSize) {
      data.setSize[key] = setSize[key];
    }
    proxy.$parent.$emit('ready', proxy);
  });
  getBlockPuzzleCaptcha()
  window.addEventListener('touchmove', move);
  window.addEventListener('mousemove', move);
  window.addEventListener('touchend', end);
  window.addEventListener('mouseup', end);
})

onUnmounted(() => {
  window.removeEventListener('touchmove', move);
  window.removeEventListener('mousemove', move);
  window.removeEventListener('touchend', end);
  window.removeEventListener('mouseup', end);
})

const barArea = computed(() => {
  return inner_base.value.querySelector('.verify-bar-area')
})

const start = (e: any) => {
  e = e || window.event;
  let x = e.clientX;
  if (e.touches) {
    x = e.touches[0].pageX;
  }
  // console.log("barArea", barArea)
  data.startLeft = Math.floor(x - barArea.value.getBoundingClientRect().left);
  data.startMoveTime = String(+new Date()); // 开始滑动的时间
  if (data.isEnd === false) {
    data.text = '';
    data.moveLeftBarBackgroundColor = '#ff6600';
    data.iconColor = '#fff';
    e.stopPropagation();
    data.status = true;
  }
}

const move = (e: any) => {
  e = e || window.event;
  if (data.status && data.isEnd === false) {
    let x = e.clientX;
    if (e.touches) {
      x = e.touches[0].pageX;
    }

    var bar_area_left = barArea.value.getBoundingClientRect().left;
    var move_block_left = x - bar_area_left; // 小方块相对于父元素的left值
    if (move_block_left >= barArea.value.offsetWidth - parseInt(String(parseInt(props.blockSize.width) / 2)) - 2) {
      move_block_left = barArea.value.offsetWidth - parseInt(String(parseInt(props.blockSize.width) / 2)) - 2;
    }
    if (move_block_left <= 0) {
      move_block_left = parseInt(String(parseInt(props.blockSize.width) / 2));
    }
    // 拖动后小方块的left值
    data.moveBlockLeft = move_block_left - data.startLeft + 'px';
    data.leftBarWidth = move_block_left - data.startLeft + 'px';
  }
}

const end = (e: any) => {
  data.endMovetime = String(+new Date());
  // 判断是否重合
  if (data.status && data.isEnd === false) {
    var moveLeftDistance = parseInt((data.moveBlockLeft || '').replace('px', ''));
    moveLeftDistance = (moveLeftDistance * 310) / parseInt(String(data.setSize.imgWidth));

    verifyBlockPuzzleCaptchaInfo({
      token: data.backToken,
      point_json: JSON.stringify({x: moveLeftDistance, y: 5.0}),
    }).then((res) => {
      if (res.status == 200) {
        data.iconColor = '#fff'
        data.iconClass = 'icon-check'
        data.showRefresh = false
        data.isEnd = true
        setTimeout(() => {
            proxy.$parent.clickShow = false;
            refresh()
          }, 1500);
        data.passFlag = true
        data.tipWords = `${((data.endMovetime - data.startMoveTime) / 1000).toFixed(2)}s 验证成功}`
        setTimeout(() => {
          data.tipWords = '';
          emit("myclick")
          // proxy.$parent.closeBox();
          // proxy.$parent.$emit('success', {data});
        }, 1000);
      }else{
        data.iconColor = '#fff';
        data.iconClass = 'icon-close';
        data.passFlag = false;
        setTimeout(function () {
          refresh()
        }, 1000);
        proxy.$parent.$emit('error', this);
        data.tipWords = '验证失败';
        setTimeout(() => {
          data.tipWords = '';
        }, 1000);
      }
    })

    data.status = false;
  }
}

const refresh = () => {
  data.showRefresh = true;
  data.finishText = '';

  data.transitionLeft = 'left .3s';
  data.moveBlockLeft = 0;

  data.leftBarWidth = undefined;
  data.transitionWidth = 'width .3s';

  data.moveBlockBackgroundColor = '#fff';
  data.moveLeftBarBackgroundColor = '#fff';
  data.iconColor = '#000';
  data.iconClass = 'icon-right';
  data.isEnd = false;

  getBlockPuzzleCaptcha()
  setTimeout(() => {
    data.transitionWidth = '';
    data.transitionLeft = '';
    data.text = props.explain;
  }, 300);
}


const getBlockPuzzleCaptcha = () => {
  getBlockPuzzleCaptchaInfo().then((res) => {
    data.backImgBase = res .backgroundBase64ImageStr
    data.blockBackImgBase = res.picCheckerBase64ImageStr
    data.backToken = res.token
  })
}

</script>

<script lang="ts">
export default {
  name: "blockCaptchaComp"
}
</script>

<template>
  <div style="position: relative" ref="inner_base">
    <div class="ellipse"></div>
    <div class="verify-img-out" :style="{ height: parseInt(String(data.setSize.imgHeight)) + 'px' }">
      <div class="verify-img-panel" :style="{ width: data.setSize.imgWidth, height: data.setSize.imgHeight }">
        <img
            :src="data.backImgBase ? data.backImgBase : data.defaultImg"
            alt=""
            style="width: 100%; height: 100%; display: block"
        />
        <div class="verify-refresh" v-show="data.showRefresh" @click="refresh">
          <Icon custom="fth-iconfont-Reload" class="iconfont" size="16" style="color: #fff"/>
        </div>
        <transition name="tips">
          <span v-if="data.tipWords" class="verify-tips" :class="data.passFlag ? 'suc-bg' : 'err-bg'">{{
              data.tipWords
            }}</span>
        </transition>
      </div>
    </div>
    <!-- 公共部分 -->
    <div
        class="verify-bar-area"
        :style="{
          width: data.setSize.imgWidth,
          height: props.barSize.height,
          'line-height': props.barSize.height,
      }"
    >
      <span class="verify-msg">滑动滑块开始验证</span>
      <div
          class="verify-left-bar"
          :style="{
            width: data.leftBarWidth !== undefined ? data.leftBarWidth : '16px',
            height: '34px',
            'background-color': data.moveLeftBarBackgroundColor,
            transaction: String(data.transitionWidth),
        }"
      >
        <span class="verify-msg" v-text="data.finishText"/>
        <div
            class="verify-move-block"
            :style="{
            width: '16px',
            height: '42px',
            'background-color': data.moveBlockBackgroundColor,
            left: data.moveBlockLeft,
            transition: data.transitionLeft,
          }"
            @touchstart="start"
            @mousedown="start"
        >
          <i class="line line_left"></i>
          <i class="line line_right"></i>
          <div
              class="verify-sub-block"
              :style="{
                width: '50px',
                height: data.setSize.imgHeight,
                top: '-' + (parseInt(String(data.setSize.imgHeight)) + props.vSpace + 4) + 'px !important',
                'background-size': data.setSize.imgWidth + ' ' + data.setSize.imgHeight,
            }"
          >
            <img
                :src="data.blockBackImgBase"
                alt=""
                :draggable="false"
                style="width: 100%; height: 100%; display: block"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>